package com.piece.module.file.util.excel;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.core.framework.annotation.office.ExcelCellConvert;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddressList;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 填充Excel单元格数据
 */
public class ExcelWriterHandler implements SheetWriteHandler {

    private int rowSize;
    private Map<Integer, String[]> dropDownMap = new HashMap<>();
    private Map<Integer, String> promptMap = new HashMap<>();

    public ExcelWriterHandler(ExcelParam param) {
        this.initParam(param);
    }

    private void initParam(ExcelParam param) {
        List data = param.getData();
        this.rowSize= data.size();

        Class type = param.getConvertType();
        if (null != type) {
            Field[] fields = type.getDeclaredFields();
            for (Field field : fields) {
                ExcelProperty property = field.getAnnotation(ExcelProperty.class);
                ExcelCellConvert convert = field.getAnnotation(ExcelCellConvert.class);
                if (null != property && null != convert) {
                    String[] dropDown = convert.combo();
                    if (null != dropDown && property.index() > -1) {
                        this.dropDownMap.put(property.index(), dropDown);
                    }
                    String prompt = convert.prompt();
                    if (StringUtil.isNotEmpty(prompt)) {
                        this.promptMap.put(property.index(), prompt);
                    }
                }
            }
        }
    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        if (!dropDownMap.isEmpty()) {
            Sheet sheet = writeSheetHolder.getSheet();
            DataValidationHelper helper = sheet.getDataValidationHelper();

            dropDownMap.forEach((index, dropDown) -> {
                if (null != dropDown && dropDown.length > 0) {
                    CellRangeAddressList cellRange = new CellRangeAddressList(1, rowSize, index, index);
                    DataValidationConstraint constraint = helper.createExplicitListConstraint(dropDown);
                    DataValidation validation = helper.createValidation(constraint, cellRange);
                    validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
                    validation.setShowErrorBox(true);
                    validation.setSuppressDropDownArrow(true);
                    sheet.addValidationData(validation);
                }
            });
        }

        if (!promptMap.isEmpty()) {
            Sheet sheet = writeSheetHolder.getSheet();
            DataValidationHelper helper = sheet.getDataValidationHelper();

            promptMap.forEach((index, prompt) -> {
                if (StringUtil.isNotEmpty(prompt)) {
                    CellRangeAddressList cellRange = new CellRangeAddressList(1, rowSize, index, index);
                    DataValidationConstraint constraint = helper.createCustomConstraint("*");
                    DataValidation validation = helper.createValidation(constraint, cellRange);
                    validation.createPromptBox("info", prompt);
                    sheet.addValidationData(validation);
                }
            });
        }
    }
}
